
/*
//数码管改成局部静态变量
#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

unsigned char code LedChar[] = {  //数码管显示字符转换表
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
    0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = {  //数码管显示缓冲区，初值0xFF确保启动时都不亮
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned char flag1s = 0;  //1秒定时标志

void main()
{
    unsigned long sec = 0;  //记录经过的秒数

    EA = 1;       //使能总中断
    ENLED = 0;    //使能U3，选择控制数码管
    ADDR3 = 1;    //因为需要动态改变ADDR0-2的值，所以不需要再初始化了
    TMOD = 0x01;  //设置T0为模式1
    TH0  = 0xFC;  //为T0赋初值0xFC67，定时1ms
    TL0  = 0x67;
    ET0  = 1;     //使能T0中断
    TR0  = 1;     //启动T0
    
    while (1)
    {
        if (flag1s == 1)  //判断1秒定时标志
        {
            flag1s = 0;   //1秒定时标志清零
            sec++;        //秒计数自加1
            //以下代码将sec按十进制位从低到高依次提取并转为数码管显示字符
            LedBuff[0] = LedChar[sec%10];
            LedBuff[1] = LedChar[sec/10%10];
            LedBuff[2] = LedChar[sec/100%10];
            LedBuff[3] = LedChar[sec/1000%10];
            LedBuff[4] = LedChar[sec/10000%10];
            LedBuff[5] = LedChar[sec/100000%10];
        }
    }
}
// 定时器0中断服务函数 
void InterruptTimer0() interrupt 1
{
    //static 只执行一次操作
    static unsigned char i = 0;   //动态扫描的索引，定义为局部静态变量
    static unsigned int cnt = 0;  //记录T1中断次数，定义为局部静态变量

    TH0 = 0xFC;  //重新加载初值
    TL0 = 0x67;
    cnt++;       //中断次数计数值加1
    if (cnt >= 1000)  //中断1000次即1秒
    {
        cnt = 0;      //清零计数值以重新开始下1秒计时
        flag1s = 1;   //设置1秒定时标志为1
    }
    //以下代码完成数码管动态扫描刷新
    P0 = 0xFF;   //显示消隐
    switch (i)
    {
        case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
        case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
        case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
        case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
        case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
        case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
        default: break;
    }
}
*/




/*
//点阵左上角一个灯亮
#include<reg52.h>

sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
sbit LED=P0^0;
void main()
{
    ENLED=0;//U4  74HC138
    ADDR3=0;
    ADDR0=0;
    ADDR1=0;
    ADDR2=0;

    LED=0;//点亮P0.0
    while(1);
}
*/




/*
//点亮一行P0
#include<reg52.h>

sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;

void main()
{
    ENLED=0;//U4  74HC138
    ADDR3=0;
    ADDR0=0;
    ADDR1=0;
    ADDR2=0;

    P0=0x00;//点亮P0一行
    while(1);
}
*/



/*
//全部点亮   8*8
#include<reg52.h>

sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;

void main()
{
    EA=1;//中断总开关
    ENLED=0;//U4  74HC138
    ADDR3=0;
    TMOD=0x01;//定时器0打开
    TH0=0xFC;//定时1ms
    TL0=0x67;
    ET0=1;//定时器0中断
    TR0=1;
    while(1);
}
//中断函数
void InterruptTimer() interrupt 1
{
    static unsigned char i=0;//静态变量（行数） 初始化从第一行开始
    TH0=0xFC;//定时1ms
    TL0=0x67;
    P0=0xFF;//先关闭  初始化  //消除鬼影

    switch(i)
    {
        case 0:ADDR0=0;ADDR1=0;ADDR2=0;i++;P0=0x00;break;
        case 1:ADDR0=1;ADDR1=0;ADDR2=0;i++;P0=0x00;break;
        case 2:ADDR0=0;ADDR1=1;ADDR2=0;i++;P0=0x00;break;
        case 3:ADDR0=1;ADDR1=1;ADDR2=0;i++;P0=0x00;break;
        case 4:ADDR0=0;ADDR1=0;ADDR2=1;i++;P0=0x00;break;
        case 5:ADDR0=1;ADDR1=0;ADDR2=1;i++;P0=0x00;break;
        case 6:ADDR0=0;ADDR1=1;ADDR2=1;i++;P0=0x00;break;
        case 7:ADDR0=1;ADDR1=1;ADDR2=1;i=0;P0=0x00;break;
        default:break;
    }
}
*/


/*
//爱心    字模提取  0xFF,0x99,0x00,0x00,0x00,0x81,0xC3,0xE7
#include<reg52.h>

sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;

//把取模放数组里
unsigned char code image[]={
    0xFF,0x99,0x00,0x00,0x00,0x81,0xC3,0xE7
};

void main()
{
    EA=1;//中断总开关
    ENLED=0;//U4  74HC138
    ADDR3=0;
    TMOD=0x01;//定时器0打开
    TH0=0xFC;//定时1ms
    TL0=0x67;
    ET0=1;//定时器0中断
    TR0=1;
    while(1);
}
//中断函数
void InterruptTimer() interrupt 1
{
    static unsigned char i=0;//静态变量（行数） 初始化从第一行开始
    TH0=0xFC;//定时1ms
    TL0=0x67;
    P0=0xFF;//先关闭  初始化  //消除鬼影

    switch(i)
    {
        case 0:ADDR0=0;ADDR1=0;ADDR2=0;i++;P0=image[0];break;
        case 1:ADDR0=1;ADDR1=0;ADDR2=0;i++;P0=image[1];break;
        case 2:ADDR0=0;ADDR1=1;ADDR2=0;i++;P0=image[2];break;
        case 3:ADDR0=1;ADDR1=1;ADDR2=0;i++;P0=image[3];break;
        case 4:ADDR0=0;ADDR1=0;ADDR2=1;i++;P0=image[4];break;
        case 5:ADDR0=1;ADDR1=0;ADDR2=1;i++;P0=image[5];break;
        case 6:ADDR0=0;ADDR1=1;ADDR2=1;i++;P0=image[6];break;
        case 7:ADDR0=1;ADDR1=1;ADDR2=1;i=0;P0=image[7];break;
        default:break;
    }
}
*/


/*
//向上移动 动态 □ I ❤ U □   字模提取   
// 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0xE7,0xE7,0xE7,0xE7,0xE7,0xC3,0xFF,0x99,
// 0x00,0x00,0x00,0x81,0xC3,0xE7,0xFF,0x99,0x99,0x99,0x99,0x99,0x81,0xC3,0xFF,0xFF,
// 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
#include<reg52.h>

sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;

//把取模放数组里
unsigned char code image[]={
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0xE7,0xE7,0xE7,0xE7,0xE7,0xC3,0xFF,0x99,
0x00,0x00,0x00,0x81,0xC3,0xE7,0xFF,0x99,0x99,0x99,0x99,0x99,0x81,0xC3,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};

void main()
{
    EA=1;//中断总开关
    ENLED=0;//U4  74HC138
    ADDR3=0;
    TMOD=0x01;//定时器0打开
    TH0=0xFC;//定时1ms
    TL0=0x67;
    ET0=1;//定时器0中断
    TR0=1;
    while(1);
}
//中断函数
void InterruptTimer() interrupt 1
{
    static unsigned char i=0;//静态变量（行数） 初始化从第一行开始
    static unsigned char index=0;//从起始行开始 显示8*8   显示图片张数
    static unsigned char timer=0;//1ms刷新

    TH0=0xFC;//定时1ms
    TL0=0x67;
    P0=0xFF;//先关闭  初始化  //消除鬼影----消隐

    switch(i)  //从0-7到1-8到2-9......
    {
        case 0:ADDR0=0;ADDR1=0;ADDR2=0;i++;P0=image[index+0];break;
        case 1:ADDR0=1;ADDR1=0;ADDR2=0;i++;P0=image[index+1];break;
        case 2:ADDR0=0;ADDR1=1;ADDR2=0;i++;P0=image[index+2];break;
        case 3:ADDR0=1;ADDR1=1;ADDR2=0;i++;P0=image[index+3];break;
        case 4:ADDR0=0;ADDR1=0;ADDR2=1;i++;P0=image[index+4];break;
        case 5:ADDR0=1;ADDR1=0;ADDR2=1;i++;P0=image[index+5];break;
        case 6:ADDR0=0;ADDR1=1;ADDR2=1;i++;P0=image[index+6];break;
        case 7:ADDR0=1;ADDR1=1;ADDR2=1;i=0;P0=image[index+7];break;
        default:break;
    }
    timer++;
    if(timer>=250)  //250ms切换一张图片
    {
        timer=0;
        index++;
        if(index>=32)  //最多32张图片
        {
            index=0;  //循环播放图片
        }
    }
}
*/




//向左移动 动态 □ I ❤ U □   字模提取   

#include<reg52.h>

sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;

//31张图片 每张图片8个元素    每张图片相当于1帧   二维数组（行优先）
unsigned char code image[31][8]={
    {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,},
    {0xFF,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,},
    {0xFF,0x3F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,},
    {0xFF,0x1F,0x3F,0x3F,0x3F,0x3F,0x3F,0x1F,},
    {0xFF,0x0F,0x9F,0x9F,0x9F,0x9F,0x9F,0x0F,},
    {0xFF,0x87,0xCF,0xCF,0xCF,0xCF,0xCF,0x87,},
    {0xFF,0xC3,0xE7,0xE7,0xE7,0xE7,0xE7,0xC3,},
    {0xFF,0xE1,0x73,0x73,0x73,0xF3,0xF3,0xE1,},
    {0xFF,0x70,0x39,0x39,0x39,0x79,0xF9,0xF0,},
    {0xFF,0x38,0x1C,0x1C,0x1C,0x3C,0x7C,0xF8,},
    {0xFF,0x9C,0x0E,0x0E,0x0E,0x1E,0x3E,0x7C,},
    {0xFF,0xCE,0x07,0x07,0x07,0x0F,0x1F,0x3E,},
    {0xFF,0x67,0x03,0x03,0x03,0x07,0x0F,0x9F,},
    {0xFF,0x33,0x01,0x01,0x01,0x03,0x87,0xCF,},
    {0xFF,0x99,0x00,0x00,0x00,0x81,0xC3,0xE7,},
    {0xFF,0xCC,0x80,0x80,0x80,0xC0,0xE1,0xF3,},
    {0xFF,0xE6,0xC0,0xC0,0xC0,0xE0,0xF0,0xF9,},
    {0xFF,0x73,0x60,0x60,0x60,0x70,0x78,0xFC,},
    {0xFF,0x39,0x30,0x30,0x30,0x38,0x38,0x7C,},
    {0xFF,0x9C,0x98,0x98,0x98,0x9C,0x1E,0x3F,},
    {0xFF,0xCE,0xCC,0xCC,0xCC,0xCE,0x0F,0x1F,},
    {0xFF,0xE7,0xE6,0xE6,0xE6,0xE7,0x07,0x0F,},
    {0xFF,0x73,0x73,0x73,0x73,0x73,0x03,0x07,},
    {0xFF,0x9C,0x9C,0x9C,0x9C,0x9C,0x80,0xC1,},
    {0xFF,0xCE,0xCE,0xCE,0xCE,0xCE,0xC0,0xE0,},
    {0xFF,0xE7,0xE7,0xE7,0xE7,0xE7,0xE0,0xF0,},
    {0xFF,0xF3,0xF3,0xF3,0xF3,0xF3,0xF0,0xF8,},
    {0xFF,0xF9,0xF9,0xF9,0xF9,0xF9,0xF8,0xFC,},
    {0xFF,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFE,},
    {0xFF,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,}
    };

void main()
{
    EA=1;//中断总开关
    ENLED=0;//U4  74HC138
    ADDR3=0;
    TMOD=0x01;//定时器0打开
    TH0=0xFC;//定时1ms
    TL0=0x67;
    ET0=1;//定时器0中断
    TR0=1;
    while(1);
}
//中断函数
void InterruptTimer() interrupt 1
{
    static unsigned char i=0;//静态变量（行数） 初始化从第一行开始
    static unsigned char index=0;//从起始行开始 显示8*8   显示图片张数
    static unsigned char timer=0;//1ms刷新

    TH0=0xFC;//定时1ms
    TL0=0x67;
    P0=0xFF;//先关闭  初始化  //消除鬼影----消隐

    switch(i)  //从0-7到1-8到2-9......
    {
        case 0:ADDR0=0;ADDR1=0;ADDR2=0;i++;P0=image[index][0];break;
        case 1:ADDR0=1;ADDR1=0;ADDR2=0;i++;P0=image[index][1];break;
        case 2:ADDR0=0;ADDR1=1;ADDR2=0;i++;P0=image[index][2];break;
        case 3:ADDR0=1;ADDR1=1;ADDR2=0;i++;P0=image[index][3];break;
        case 4:ADDR0=0;ADDR1=0;ADDR2=1;i++;P0=image[index][4];break;
        case 5:ADDR0=1;ADDR1=0;ADDR2=1;i++;P0=image[index][5];break;
        case 6:ADDR0=0;ADDR1=1;ADDR2=1;i++;P0=image[index][6];break;
        case 7:ADDR0=1;ADDR1=1;ADDR2=1;i=0;P0=image[index][7];break;
        default:break;
    }
    timer++;//动态刷新
    if(timer>=250)  //250ms切换一张图片
    {
        timer=0;
        index++;
        if(index>=30)  //最多31张图片  0-30
        {
            index=0;  //循环播放图片
        }
    }
}